#include "SchedulerInc.h"

using namespace bimar_scheduler_lib;

CJobsWorker::CJobsWorker()
:CGThreadWrapper("CJobsWorker")
{

}

CJobsWorker::~CJobsWorker()
{
  Destroy();
}

gboolean CJobsWorker::Create()
{
  return TRUE;
}

gboolean CJobsWorker::Destroy()
{
  Stop();
  DestroyExecutors();
  DestroyJobs();

  return TRUE;
}

gboolean CJobsWorker::DestroyJobs()
{
  CGAutoLock lock(&m_jobsCS);
  
  for(JobIt it=m_jobs.begin(); it!=m_jobs.end(); it++)
  {
    CJob *job = *it;
    if(job)
      delete job;
  }
  
  m_jobs.clear();
  m_submittedJobList.clear();
  m_runningJobList.clear();
  m_doneJobList.clear();

  return TRUE;
}

gboolean CJobsWorker::DestroyExecutors()
{
  CGAutoLock lock(&m_jobExecCS);
  for(JobExecutorIt it=m_jobExec.begin(); it!=m_jobExec.end(); it++)
  {
	CJobExecutor *exec = *it;
    if(exec)
      delete exec;
  }
  m_jobExec.clear();

  return TRUE;
}

gboolean CJobsWorker::Start()
{
  if(IsThreadRunning())
	  return FALSE;
  
  return CreateThread();  
}

gboolean CJobsWorker::Stop()
{
  if(!IsThreadRunning())
    return FALSE;

  return DestroyThread();
}

gboolean CJobsWorker::AddJob(CJob *job)
{
  g_return_val_if_fail(job, FALSE);

  CGAutoLock lock(&m_jobsCS);

  /* to main list */
  m_jobs.push_back(job);

  /* to submitted list */
  m_submittedJobList.push_back(job);

  return TRUE;
}

CJob * CJobsWorker::GetNextJobToExecute()
{
  CGAutoLock lock(&m_jobsCS);
  
  JobIt it = m_jobs.begin();
  if(it==m_submittedJobList.end())
    return NULL;

  CJob *job = *it;
  m_submittedJobList.pop_front();

  return job;
}

gboolean CJobsWorker::StartJob(CJobExecutor *executor, CJob *job)
{
  g_return_val_if_fail(executor && job, FALSE);

  CGAutoLock lock(&m_jobsCS);
  
  m_runningJobList.push_back(job);
  
  return executor->StartJob(job);
}
